/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package desarrollosoft.ghce.dao.implementaciones;

import desarrollosoft.ghce.dao.interfaces.IBajaLogicaPacienteDAO;
import desarrollosoft.ghce.entidades.BajaLogicaPaciente;
import desarrollosoft.ghce.entidades.Paciente;
import desarrollosoft.ghce.entidades.Sexo;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author ariel
 */
@Repository("bajaLogicaPacienteDAO")
public class BajaLogicaPacienteDAO implements IBajaLogicaPacienteDAO {
    
    @PersistenceContext
    EntityManager entityManager;

    @Override
    @Transactional(propagation = Propagation.MANDATORY)
    public void crearBajaLogica(BajaLogicaPaciente bajaLogicaPaciente) {
        entityManager.persist(bajaLogicaPaciente);
    }

    @Override
    @Transactional(propagation = Propagation.MANDATORY)
    public void eliminarBajaLogica(BajaLogicaPaciente bajaLogica) throws Exception {
        entityManager.remove( entityManager.merge(bajaLogica) );
    }

    @Override
    public Double obtenerBajasSobreTotalEnFechaEdadesSexo(Sexo sexo, Date fechaDesde, Date fechaHasta, int edadDesde, int edadHasta) {
        String jpql = "SELECT p FROM Paciente p JOIN p.bajaLogicaPaciente b WHERE b.fechaSuceso BETWEEN :fechaDesde AND :fechaHasta";
        if (sexo != null) {
            jpql += " AND p.sexo = :sexo";
        }
        Query consultaBajasLogicas = entityManager.createQuery(jpql);
        consultaBajasLogicas.setParameter("fechaDesde", fechaDesde);
        consultaBajasLogicas.setParameter("fechaHasta", fechaHasta);
        if (sexo != null) {
            consultaBajasLogicas.setParameter("sexo", sexo);
        }
        List<Paciente> listaPacientesDadosBaja = consultaBajasLogicas.getResultList();
        if (listaPacientesDadosBaja.isEmpty()) {
            return 0.0;
        }
        Query consultaTotalPacientes = entityManager.createQuery(
                "SELECT COUNT(p) FROM Paciente p"
        );
        int cantidadTotalPacientes = ((Long) consultaTotalPacientes.getSingleResult()).intValue();
        int bajasPaciente = 0;
        for (Paciente paciente : listaPacientesDadosBaja) {
            int edad = calcularEdadEnMomento(paciente.getFechaNacimiento(), paciente.getBajaLogicaPaciente().getFechaSuceso());
            if (edadDesde <= edad && edad <= edadHasta) {
                bajasPaciente++;
            }
        }
        return ( ((double) bajasPaciente) / ((double) cantidadTotalPacientes) );
    }
    
    private int calcularEdadEnMomento(Date fechaNacimiento, Date fechaBajaLogica) {
        
        GregorianCalendar fechaNacimientoCal = new GregorianCalendar();
        fechaNacimientoCal.setTime(fechaNacimiento);
        GregorianCalendar fechaSucesoCal = new GregorianCalendar();
        fechaSucesoCal.setTime(fechaBajaLogica);

        //Se restan las fechas
        int anio = fechaSucesoCal.get(Calendar.YEAR)- fechaNacimientoCal.get(Calendar.YEAR);
        int mes = fechaSucesoCal.get(Calendar.MONTH)- fechaNacimientoCal.get(Calendar.MONTH);
        int dia = fechaSucesoCal.get(Calendar.DATE)- fechaNacimientoCal.get(Calendar.DATE);
        //Se ajusta el año dependiendo el mes y el día
        if (mes < 0 || ( mes == 0 && dia < 0) ){
            anio--;
        }
        return anio;
    }
}
